package com.partsoft.spring.zks;


import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zkplus.databind.DataBinder;


@SuppressWarnings({"serial"})
public class AnnotateDataBinderComponent extends ExtHtmlMacroComponent {
	
	public static final String ARG_DATABINDER = "databinder";
	
	private transient DataBinder dataBinder;
	
	protected Object dataModel = "未设置数据模型";

	public AnnotateDataBinderComponent() {
		super();
	}
	
	public AnnotateDataBinderComponent(String macroURI) {
		super(macroURI);
	}
	
	/**
	 * 在创建子组件之前的动作
	 */
	@Override
	protected void beforeCreateMacroChildren() {}
	
	/**
	 * 初始化数据模型
	 */
	private void initDataModel() {
		doSetDataModel(getDataModel());
	}
	
	/**
	 * 创建一个数据帮定器
	 * @return 如果返回null则表示不支持数据帮定器
	 */
	protected DataBinder createDataBinder() {
		return isInline() ? null : new AnnotateDataBinder(this);
	}
	
	/**
	 * 在此方法中帮定页面数据
	 * @param dataBinder
	 */
	protected void bindDataBean(DataBinder dataBinder) {
		Object dataModel = getDataModel();
		if (dataModel != null) {
			dataBinder.bindBean(ARG_DATAMODEL, dataModel);
			dataBinder.bindBean("datamodel", dataModel);
		}
	}
	
	final protected DataBinder getDataBinder() {
		return this.dataBinder;
	}
	
	/**
	 * 在创建在子组件之后的动作<br/>
	 * 注入当前成员变量<br/>
	 * 注入原则:<br/>
	 * <ul>
	 * 	<li>所有名称与zul定义中的控件id一致则注入;</li>
	 * <li>所有与Spring中定义的服务名称一致则注入</li>
	 * </ul>
	 * 绑定所有控件的事件<br/>
	 * 绑定原则:<br/>
	 * <ul>
	 * <li>所有该类(包括子类)的方法定义如public void onEventName$zulControlId(ForwardEvent forwardevent)都表示监听具体的事件</li>
	 * </ul>
	 * 加载数据绑定
	 */
	@Override
	protected void afterCreateMacroChildren() {
		//初始化数据帮定
		initDataModel();
		initDataBinderCombination();
	}
	
	/**
	 * 初始化数据帮定
	 */
	private void initDataBinderCombination() {
		this.removeAttribute(AnnotateDataBinder.ARG_DATABINDER_REGISTED);
		this.dataBinder = createDataBinder();
		if (this.dataBinder != null) {
			bindDataBean(this.dataBinder);
			this.setAttribute(ARG_DATABINDER, this.dataBinder);
			this.dataBinder.loadAll();
			Events.postEvent(new Event(ON_DATALOAD, this));
		}
	}
	
	private void doSetDataModel(Object dataModel) {
		this.dataModel = dataModel;
		if (this.dataModel != null) {
			this.setDynamicProperty(ARG_DATAMODEL, this.dataModel);
			setAttribute(ARG_DATAMODEL, dataModel);
			setAttribute("datamodel", dataModel);
		}
	}
	
	public void setDataModel(Object dataModel) {
		if (isAlreadyCompose()) {
			if (dataModel != null) {
				loadDataModelParameter(dataModel);
			}
			doSetDataModel(dataModel);
			loadData();
		} else {
			doSetDataModel(dataModel);
		}
	}
	
	protected void loadDataModelParameter(Object dataModel) {
	}

	public Object getDataModel() {
		return dataModel;
	}


	/**
	 * 装载数据
	 */
	public void loadData() {
		if (isAlreadyCompose()) {
			if (dataBinder != null) {
				if (getDataModel() == null) {
					initDataModel();
				}
				//do refresh dataModel
				bindDataBean(this.getDataBinder());
				dataBinder.loadAll();
				Events.postEvent(new Event(ON_DATALOAD, this));
			}
		} 
	}	
	
	@Override
	protected void doAfterClone() {
		initDataModel();
		initDataBinderCombination();
	}
}
